home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / ax25user.c < prev    next >
C/C++ Source or Header  |  1993-11-18  |  5KB  |  228 lines

  1. /* User interface subroutines for AX.25
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "config.h"
  6. #ifdef AX25
  7. #include "mbuf.h"
  8. #include "timer.h"
  9. #include "iface.h"
  10. #include "lapb.h"
  11. #include "ax25.h"
  12. #include "lapb.h"
  13. #include <ctype.h>
  14.  
  15. /* Open an AX.25 connection */
  16. struct ax25_cb *
  17. open_ax25(iface,local,theremote,mode,window,r_upcall,t_upcall,s_upcall,user)
  18. struct iface *iface;    /* Interface */
  19. char *local;        /* Local address */
  20. char *theremote;        /* theremote address */
  21. int mode;        /* active/passive/server */
  22. int16 window;        /* Window size in bytes */
  23. void (*r_upcall)();    /* Receiver upcall handler */
  24. void (*t_upcall)();    /* Transmitter upcall handler */
  25. void (*s_upcall)();    /* State-change upcall handler */
  26. int user;        /* User linkage area */
  27. {
  28.     struct ax25_cb *axp;
  29.     char remtmp[AXALEN];
  30.  
  31.     if(theremote == NULLCHAR){
  32.         theremote = remtmp;
  33.         setcall(theremote," ");
  34.     }
  35.     if((axp = find_ax25(local,theremote,iface)) != NULLAX25 && axp->state != LAPB_DISCONNECTED)
  36.         return NULLAX25;    /* Only one to a customer */
  37.     if(axp == NULLAX25 && (axp = cr_ax25(local,theremote,iface)) == NULLAX25)
  38.         return NULLAX25;
  39. /*
  40.     memcpy(axp->theremote,theremote,AXALEN);
  41.     memcpy(axp->local,local,AXALEN);
  42.  */
  43.     axp->iface = iface;
  44.     axp->window = window;
  45.     axp->r_upcall = r_upcall;
  46.     axp->t_upcall = t_upcall;
  47.     axp->s_upcall = s_upcall;
  48.     axp->user = user;
  49.  
  50.     switch(mode){
  51.     case AX_SERVER:
  52.         axp->flags.clone = 1;
  53.     case AX_PASSIVE:    /* Note fall-thru */
  54.         axp->state = LAPB_LISTEN;
  55.         return axp;
  56.     case AX_ACTIVE:
  57.         break;
  58.     }    
  59.     switch(axp->state){
  60.     case LAPB_DISCONNECTED:
  61.         est_link(axp);
  62.         lapbstate(axp,LAPB_SETUP);
  63.         break;
  64.     case LAPB_SETUP:
  65.         free_q(&axp->txq);
  66.         break;
  67.     case LAPB_DISCPENDING:    /* Ignore */
  68.         break;
  69.     case LAPB_RECOVERY:
  70.     case LAPB_CONNECTED:
  71.         free_q(&axp->txq);
  72.         est_link(axp);
  73.         lapbstate(axp,LAPB_SETUP);
  74.         break;
  75.     }
  76.     return axp;
  77. }
  78.  
  79. /* Send data on an AX.25 connection. Caller provides optional PID. If
  80.  * a PID is provided, then operate in stream mode, i.e., a large packet
  81.  * is automatically packetized into a series of paclen-sized data fields.
  82.  *
  83.  * If pid == -1, it is assumed the packet (which may actually be a queue
  84.  * of distinct packets) already has a PID on the front and it is passed
  85.  * through directly even if it is very large.
  86.  */
  87. int
  88. send_ax25(axp,bp,pid)
  89. struct ax25_cb *axp;
  90. struct mbuf *bp;
  91. int pid;
  92. {
  93.     struct mbuf *bp1;
  94.     int16 offset,len,size;
  95.  
  96.     if(axp == NULLAX25 || bp == NULLBUF) {
  97.         free_p(bp);
  98.         return -1;
  99.     }
  100.  
  101.     if(pid != -1){
  102.         offset = 0;
  103.         len = len_p(bp);
  104.         /* It is important that all the pushdowns be done before
  105.          * any part of the original packet is freed.
  106.          * Otherwise the pushdown might erroneously overwrite
  107.          * a part of the packet that had been duped and freed.
  108.          */
  109.         while(len != 0){
  110.             size = min(len,axp->paclen);
  111.             dup_p(&bp1,bp,offset,size);
  112.             len -= size;
  113.             offset += size;
  114.             bp1 = pushdown(bp1,1);
  115.             bp1->data[0] = pid;
  116.             enqueue(&axp->txq,bp1);
  117.         }
  118.         free_p(bp);
  119.     } else {
  120.         enqueue(&axp->txq,bp);
  121.     }
  122.     return lapb_output(axp);
  123. }
  124.  
  125. /* Receive incoming data on an AX.25 connection */
  126. struct mbuf *
  127. recv_ax25(axp,cnt)
  128. struct ax25_cb *axp;
  129. int16 cnt;
  130. {
  131.     struct mbuf *bp;
  132.  
  133.     if(axp->rxq == NULLBUF)
  134.         return NULLBUF;
  135.  
  136.     if(cnt == 0){
  137.         /* This means we want it all */
  138.         bp = axp->rxq;
  139.         axp->rxq = NULLBUF;
  140.     } else {
  141.         bp = ambufw(cnt);
  142.         bp->cnt = pullup(&axp->rxq,bp->data,cnt);
  143.     }
  144.     /* If this has un-busied us, send a RR to reopen the window */
  145.     if(len_p(axp->rxq) < axp->window
  146.      && (len_p(axp->rxq) + bp->cnt) >= axp->window)
  147.         sendctl(axp,LAPB_RESPONSE,RR);
  148.  
  149.     return bp;
  150. }
  151.  
  152. /* Close an AX.25 connection */
  153. int
  154. disc_ax25(axp)
  155. struct ax25_cb *axp;
  156. {
  157.     if(axp == NULLAX25)
  158.         return -1;
  159.     switch(axp->state){
  160.     case LAPB_DISCONNECTED:
  161.         break;        /* Ignored */
  162.     case LAPB_LISTEN:
  163.         del_ax25(axp);
  164.         break;
  165.     case LAPB_DISCPENDING:
  166.         lapbstate(axp,LAPB_DISCONNECTED);
  167.         break;
  168.     case LAPB_CONNECTED:
  169.     case LAPB_RECOVERY:
  170.         free_q(&axp->txq);
  171.         axp->retries = 0;
  172.         sendctl(axp,LAPB_COMMAND,DISC|PF);
  173.         stop_timer(&axp->t3);
  174.         start_timer(&axp->t1);
  175.         lapbstate(axp,LAPB_DISCPENDING);
  176.         break;
  177.     }
  178.     return 0;
  179. }
  180.  
  181. /* Verify that axp points to a valid ax25 control block */
  182. int
  183. ax25val(axp)
  184. struct ax25_cb *axp;
  185. {
  186.     register struct ax25_cb *axp1;
  187.  
  188.     if(axp == NULLAX25)
  189.         return 0;    /* Null pointer can't be valid */
  190.     for(axp1 = Ax25_cb;axp1 != NULLAX25; axp1 = axp1->next)
  191.         if(axp1 == axp)
  192.             return 1;
  193.     return 0;
  194. }
  195.  
  196. /* Force a retransmission */
  197. int
  198. kick_ax25(axp)
  199. struct ax25_cb *axp;
  200. {
  201.     if(!ax25val(axp))
  202.         return -1;
  203.     recover(axp);
  204.     return 0;
  205. }
  206.  
  207. /* Abruptly terminate an AX.25 connection */
  208. int
  209. reset_ax25(axp)
  210. struct ax25_cb *axp;
  211. {
  212.     void (*upcall)__ARGS((struct ax25_cb *,int));
  213.  
  214.     if(axp == NULLAX25)
  215.         return -1;
  216.     /* Be nice and send a DM - WG7J */
  217.     disc_ax25(axp);
  218.     upcall = axp->s_upcall;
  219.     lapbstate(axp,LAPB_DISCONNECTED);
  220.     /* Clean up if the standard upcall isn't in use */
  221.     if(upcall != s_ascall)
  222.         del_ax25(axp);
  223.     return 0;
  224. }
  225.  
  226. #endif
  227.  
  228.